/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package wetest;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import we.config.CConstant;
import we.dispatcher.CPacketReader;
import we.dispatcher.CPacketWriter;
import we.exception.ReadingPacketException;
import we.exception.UnsupportedTypeException;

/**
 *
 * @author trungdv2
 */
public class WeTest
{
    static int readTime = 0;
    static int writeTime = 0;
    
    final static int TIME = 990;
    
    final static int PERIOD = 500;
    final static int APPEND = 0;
    final static int LOOP = 100;
    
    public static class SocketThread extends Thread
    {        

        class ReadThread extends Thread
        {

            @Override
            public void run()
            {
                int count = 0;
                CPacketReader reader = new CPacketReader(1024);
                while (true)
                {
                    try
                    {
                        byte b = (byte) in.read();
                        //    System.out.println("read : " + b);
                        count++;
                        if (count <= 87)
                        {
                            continue;
                        }


                        reader.put(b);
                        if (reader.checkCompletedPackage())
                        {
                            //System.out.println("--------reader complete");
                            readTime++;
                            // socket.close();
//                            if ( Math.abs(readTime - writeTime) > 1)
//                            {
//                                System.out.println("read != write : " + readTime + " " + writeTime);
//                                System.exit(0);
//                            }
                            
                            try
                            {
                                if (reader.readID() == 1000)
                                {
                                    writeTime++;
                                    String s = (String) reader.read(String.class)[0];
                                    s = s.trim();
                                    //      System.out.println("read : " + s);
                                    long time = Long.parseLong(s);
                                    long kc = (System.currentTimeMillis() - time);
                                    if (kc > TIME)
                                    {
                                        System.out.println("time : " + kc);
                                    }


                                }
                            } catch (ReadingPacketException ex)
                            {
                                Logger.getLogger(WeTest.class.getName()).log(Level.SEVERE, null, ex);
                            } catch (UnsupportedTypeException ex)
                            {
                                Logger.getLogger(WeTest.class.getName()).log(Level.SEVERE, null, ex);
                            }

                            reader.clearAll();
                        }
                    } catch (ReadingPacketException ex)
                    {
                        Logger.getLogger(WeTest.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (IOException ex)
                    {
                        Logger.getLogger(WeTest.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        }

        class WriteThread extends Thread
        {

            @Override
            public void run()
            {
                final Random rand = new Random();
                Timer timer = new Timer();
                timer.schedule(new TimerTask()
                {
                    @Override
                    public void run()
                    {
                        try
                        {
                            synchronized (this)
                            {
//                                System.out.println("send");
                                writeTime++;
                                Date date = new Date();
                                CPacketWriter writer = new CPacketWriter(1024);
                                StringBuilder buidler = new StringBuilder(Long.toString(date.getTime()));
                                for (int i = 0; i < APPEND; i++)
                                    buidler.append(' ');
                                writer.write(1000, buidler.toString());
                                
                                //writer.write(1000, "abc");

                                while (writer.buffer().hasRemaining())
                                {
                                    byte b = writer.buffer().get();
                                    //   System.out.println(" write : " + b);
                                    out.write(b);
                                }
                                out.flush();
                            }
                        } catch (UnsupportedTypeException ex)
                        {
                            Logger.getLogger(WeTest.class.getName()).log(Level.SEVERE, null, ex);
                        } catch (IOException ex)
                        {
                            Logger.getLogger(WeTest.class.getName()).log(Level.SEVERE, null, ex);
                        }

                    }
                }, 1000, PERIOD);
            }
        }
        InputStream in;
        OutputStream out;
        Socket socket;

        @Override
        public void run()
        {
            try
            {
                //        Selector selector = Selector.open();
                //        SocketChannel socketChannel = SocketChannel.open();
                //        socketChannel.connect(new InetSocketAddress("localhost", 443));
//                System.out.println("starting thread .. " + Thread.currentThread().getName());
                socket = newSocket("localhost", CConstant.SERVER_PORT);
                in = socket.getInputStream();
                out = socket.getOutputStream();

                new ReadThread().start();
                new WriteThread().start();


                //System.out.println("stoped");
            } catch (Exception ex)
            {
                System.out.println(" cant connect " + Thread.currentThread().getName());
                ex.printStackTrace();
            }
        }
    }

    public static synchronized Socket newSocket(String url, int port) throws Exception
    {
        return new Socket(url, port);
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception
    {
        for (int i = 0; i < LOOP; i++)
        {
            SocketThread thread = new SocketThread();
            thread.start();
            //Thread.sleep(10);
            // new Socket("localhost", CConstant.SERVER_PORT);
        }
        // Thread.sleep(10000);
    }
}
